<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>五子棋的实现</title>
    <link rel="stylesheet" href="./index.css" />
    <!-- <script src="./index.js"></script> -->
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
  </head>
  <body>
    <div id="app" class="box flex">
      <canvas id="canvas" width="480" height="480" @click="play"></canvas>
      <!-- 对战中 -->
      <div class="btns">
        <div class="online">
          <!-- 悔棋 -->
          <button class="btn" @click="back" :disabled="arr.length < 2">
            悔棋
          </button>
          <!-- 认输/重新开始 -->
          <button @click="giveUp" class="btn" :disabled="arr.length < 2">
            重新开始
          </button>
          <button @click="save" class="btn" :disabled="arr.length < 10">
            {{arr.length<=9?'大于10手可保存':'保存对局'}}
          </button>
        </div>
        <!-- 棋局回顾 -->
        <div class="look-back">
          <!-- 上一步 下一步 -->
          <button @click="getLook" class="btn" :disabled="onLine">
            查看对局
          </button>
          <button @click="preview" class="btn" :disabled="onLine">
            上一步
          </button>
          <button @click="next" class="btn" :disabled="onLine">
            下一步
          </button>
        </div>
      </div>
      <div class="popup flex-center" v-if="mask">
        <div class="mask"></div>
        <div class="pop-content">
          <div class="text">{{poptext}}</div>
          <button @click="start">{{btnText}}</button>
        </div>
      </div>
    </div>
  </body>

  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        size: 15,
        chessWidth: 30, //棋子宽度
        arr: [], // 当居棋数组
        matrixArr: [], //棋盘矩阵
        poptext: '',
        exampleSocket: null,
        isWin: false,
        sum: 0,
        btnText: '开始游戏',
        mask: false,
        onLine: true, //是否对战
        // onLookBack: false, //是否棋局回顾
      },

      mounted() {
        this.initCanvas();
        this.initWebScoket();
      },
      methods: {
        initCanvas() {
          canvas = document.getElementById('canvas');
          ctx = canvas.getContext('2d');
          this.drawChessboard();
          this.matrixArr = Array.from({ length: this.size }, (y) =>
            Array.from({ length: this.size }, (x) => {})
          );
        },

        initWebScoket() {
          exampleSocket = new WebSocket('ws://localhost:8082');
          exampleSocket.onopen = (event) => {
            console.log('open');
          };

          exampleSocket.onmessage = (event) => {
            //收到广播数据重绘
            this.arr = JSON.parse(event.data);
            console.log(event, client, this.arr);
            this.redraw();
          };
          this.exampleSocket = exampleSocket;
        },

        start() {
          this.mask = false;
        },

        //认输
        giveUp() {
          this.arr = [];
          this.redraw();
        },
        save() {
          sessionStorage.setItem('test', this.arr);
        },

        // 查看回顾   对局中不能查看
        getLook() {},

        // 悔棋
        back() {
          this.arr.pop();
          this.exampleSocket.send(JSON.stringify(this.arr));
          this.redraw();
        },
        preview() {},
        next() {},
        /**
         *点击棋盘 添加棋子
         * 1.判断是否超过边界
         * 2.当前点是否存在棋子
         */
        play(e) {
          if (this.isWin) {
            alert('此局结束 请重新开始');
            return;
          }
          let x = Math.round(e.layerX / this.chessWidth) - 1;
          let y = Math.round(e.layerY / this.chessWidth) - 1;
          let color = this.arr.length % 2 ? 'black' : 'white';
          let index = (y - 1) * this.size + x - 1;

          if (this.isInOut(x, y)) {
            return;
          }

          if (this.isExist(x, y)) {
            return;
          }
          this.arr.push({ x, y, color });
          this.exampleSocket.send(JSON.stringify(this.arr));
          this.matrixArr[x][y] = color;
          this.drawChess({ x, y, color });
        },

        //判断输赢
        // 找到当前点 按照方向向周围循环 上一点颜色相同 则胜利机会加1
        checkWin(chess) {
          // 向上向下
          if (this.up_down(chess) == 5) {
            this.isWin = true;
            alert(chess.color + 'win');
          }
          // 向左向右;
          if (this.left_right(chess) == 5) {
            this.isWin = true;
            alert(chess.color + 'win');
          }

          // 左上右下
          if (this.left_up_right_dowm(chess) == 5) {
            this.isWin = true;
            alert(chess.color + 'win');
          }
          // 右上 左下
          if (this.right_up_left_down(chess) == 5) {
            this.isWin = true;
            alert(chess.color + 'win');
          }
        },

        up_down(chess) {
          let sum = 1;
          for (let i = chess.y - 1; i >= 0; i--) {
            if (this.matrixArr[chess.x][i] == chess.color) {
              sum++;
            } else {
              break;
            }
          }
          for (let i = chess.y + 1; i < 15; i++) {
            if (this.matrixArr[chess.x][i] == chess.color) {
              sum++;
            } else {
              break;
            }
          }
          return sum;
        },

        left_right(chess) {
          let sum = 1;
          for (let i = chess.x - 1; i >= 0; i--) {
            if (this.matrixArr[i][chess.y] == chess.color) {
              sum++;
            } else {
              break;
            }
          }

          for (let i = chess.x + 1; i < 15; i++) {
            if (this.matrixArr[i][chess.y] == chess.color) {
              sum++;
            } else {
              break;
            }
          }
          return sum;
        },

        left_up_right_dowm(chess) {
          let sum = 1;
          for (
            let i = chess.x - 1, j = chess.y - 1;
            i >= 0 && j >= 0;
            i--, j--
          ) {
            if (this.matrixArr[i][j] == chess.color) {
              sum++;
            } else {
              break;
            }
          }

          for (
            let i = chess.x + 1, j = chess.y + 1;
            i < 15 && j < 15;
            i++, j++
          ) {
            if (this.matrixArr[i][j] == chess.color) {
              sum++;
            } else {
              break;
            }
          }
          return sum;
        },

        right_up_left_down(chess) {
          let sum = 1;
          for (
            let i = chess.x + 1, j = chess.y - 1;
            i < 15 && j >= 0;
            i++, j--
          ) {
            if (this.matrixArr[i][j] == chess.color) {
              sum++;
            } else {
              break;
            }
          }

          for (
            let i = chess.x - 1, j = chess.y + 1;
            i >= 0 && j < 15;
            i--, j++
          ) {
            if (this.matrixArr[i][j] == chess.color) {
              sum++;
            } else {
              break;
            }
          }
          return sum;
        },
        //画棋盘
        drawChessboard() {
          for (let i = 0; i < 15; i++) {
            ctx.beginPath();
            ctx.moveTo(30, (i + 1) * 30);
            ctx.lineTo(450, (i + 1) * 30);

            ctx.moveTo((i + 1) * 30, 30);
            ctx.lineTo((i + 1) * 30, 450);

            ctx.closePath();
            ctx.stroke();
          }
        },

        // 棋子
        drawChess(item) {
          ctx.beginPath();
          ctx.arc(
            (item.x + 1) * this.chessWidth,
            (item.y + 1) * this.chessWidth,
            this.chessWidth / 2,
            0,
            2 * Math.PI,
            false
          );
          ctx.fillStyle = item.color;
          ctx.fill();
          ctx.stroke();

          this.checkWin(item);
        },

        // 是否超过边界
        isInOut(x, y) {
          if (x < 0 || x > this.size || y < 0 || y > this.size) {
            //   alert('请不要在棋盘外放置棋子');
            return true;
          }
          return false;
        },

        // 棋子是否已存在
        isExist(x, y) {
          let newArr = this.arr.filter((item) => {
            return item.x == x && item.y == y;
          });
          return newArr.length;
        },

        // 重绘
        redraw() {
          ctx.clearRect(
            this.chessWidth / 2,
            this.chessWidth / 2,
            this.chessWidth * this.size,
            this.chessWidth * this.size
          );
          this.drawChessboard();
          this.arr.forEach(this.drawChess);
        },
      },
    });
  </script>
</html>
